package `object`

fun main() {
    //类定义
    val student1 = Student(1, "张三", 16);
    val student2 = Student(1, "李四", 18);
    student1.study()

    // operator  plus
    val student = student1 + student2;
    println("name=${student.name}   age=${student.age}")

    //中缀函数
    println("中缀函数调用 ${student infixTest "名称"}")

    //扩展函数
    val sum = student.sum();
    println("Student类的扩展方法 ${student.sum()}")

    val s: String = "String"
    println(s.test())

    //官方扩展函数
    student.apply {
        println("官方扩展函数 apply  id=${id} name=${name}   age=${age}")
    }

    val name: String = student.let { it.name + it.name }

    //协变和逆变
    val ge1: Generic<Int> = Generic(10)
    val ge2: Generic<out Number> = ge1 //协变  父类接受子类的泛型

    val ge3: Generic<Number> = Generic(10.0)
    val ge4: Generic<in Int> = ge3 //逆变  子类接受父类的泛型

    val geSuper = GenericSuper(10)
    println("${geSuper.data}")

    //类型擦除  编译之后泛型 类型会擦除


    //data关键字
    val data = DataTest(1, "data");
    println(data)


    //枚举
    val state: LightState = LightState.YELLOW;
    state.ordinal
    state.name
    val valueOf = LightState.valueOf("RED")

    //匿名类
    val obj = object {
        fun test() {
            println("匿名类打印一下")
        }

        var age: Int = 12
    }
    obj.test()
    println(obj.age)

    val obj1 = object : KRunnable {
        override fun invoke() {
            println("打印一下 KRunnable ")
        }
    }
    obj1.invoke()

}

open class Student public constructor(val id: Int = 0, val name: String, val age: Int) {

    //次级构造函数
    constructor(name: String) : this(0, name, 12)

    lateinit var date: String;//日期

    //类初始化调用
    init {
        println("Student init1()  id=${id}  name=$name   age=$age ")
    }

    init {
        println("Student init2()  id=$id  name=$name   age=$age ")
    }

    //方法
    public open fun study() {
        println("学生$name 在学习")
    }

    //实现 student1 + student2;
    operator fun plus(another: Student): Student {
        return Student(0, this.name + another.name, this.age + another.age)
    }

    //中缀函数
    //必须是成员函数 只能有一个参数  参数不能有默认值
    infix fun infixTest(s: String): String {
        return s + s
    }

}

class AStudent constructor() : Student(1, "dd", 3) {}


/**
 * data 自动生成
 * equals()  hashCode()  toString()  component() copy() 方法
 *
 * 主构造函数必须要一个
 * 主构造函数必须标记val或者var
 * 数据类不能是抽象的 开放的 密封的或者内部的
 */
data class DataTest(val id: Int, val name: String) {}


//类的扩展
fun String.test() = "${this}类的扩展方法test()"

//类的扩展
fun Student.sum(): Int {
    return this.id + this.age;
}


class Generic<T> constructor(data: T) {}


class GenericSuper<T : Number> constructor(val data: T) {}


enum class LightState(val n: String) {
    GREEN("绿灯"), YELLOW("黄灯"), RED("红灯")
}

interface KRunnable {
    fun invoke()
}

//单例类
object Singleton {
    override fun toString(): String {
        println("我是一个单例类")
        return "我是一个单例类";
    }
}

//委托模式
interface Base {
    fun print()
}

class BaseImpl : Base {
    override fun print() {
    }
}

class Derived(val b: Base) : Base by b {}
//class Derived(var b: Base) : Base by b {
//    override fun print() = b.print()
//}

//密封类型
sealed class A {
    fun testA() {}
}

class B : A() {
    fun testB() {}
}